/* 实现 redux 的部分源码 */
import _ from "./assets/utils"

export const createStore = function (reducer) {
    if (typeof reducer !== 'function') throw new TypeError("Expected the root reducer to be a function")

    let state, // 存放公共状态
        listeners = [];//事件池

    // 获取公共状态
    const getState = function () {
        // 返回公共状态消息即可
        return state
    }
    // 向事件池中加入让组件更新的方法
    const subscribe = function (listener) {
        // 规则校验
        if (typeof listener !== 'function') throw new TypeError('listener is not a function')
        // 把传入的方法(让组件更新的方法)加入到事件池(需要做去重处理)
        console.log(listeners, 111)
        if (!listeners.includes(listener)) {
            listeners.push(listener)
        }
        // 返回一个从事件池中移除方法的函数
        return function unsubscribe() {
            let index = listeners.indexOf(listener)
            listeners.splice(index, 1)
        }
    }
    // 派发任务通知 reducer 执行
    const dispatch = function (action) {
        // 规则校验
        if (!_.isPlainObject(action)) throw new TypeError("Actions must be plain objects")
        if (typeof action.type === 'undefined') throw new TypeError("Action may not have an undefined 'type' property")
        // 把 reducer 执行，传递：公共状态、行为对象：接受执行的返回值，替换公共状态
        state = reducer(state, action)

        // 当状态更改，还需要把事件池中的方法执行
        listeners.forEach(listener => {
            listener()
        })
        return action
    }
    // redux 内部会默认进行一次 dispatch 派发，目的：给公共组件容器中的状态赋值初始值

    dispatch({
        // 取一个唯一的值
        // type: Symbol()
        type: "@@redux/INIT" + Math.random().toString(36).substring(7).split("").join(",")
    })

    return {
        getState,
        subscribe,
        dispatch
    }
}